#include "Lona.h"

#include <stdexcept>


Lona::Lona(int altoPx, int anchoPx) : 
	m_separacion( 0.05f ), 
	m_cantVertices( anchoPx * altoPx ),
	m_cantIndicesXFranja( 2 * anchoPx),
	m_longitud( ( anchoPx -1 ) * this->m_separacion )
{
	this->m_vertices = new glm::vec3[ this->m_cantVertices ];

	// Construye una trama de vertices separados cada 0.1f
	int pos = 0;
	for (int j = 0; j < altoPx; ++j){
		for (int i = 0; i < anchoPx; ++i){
			float x = i * this->m_separacion;
			float y = j * this->m_separacion;

			this->m_vertices[pos++] = glm::vec3(x, y, 0.0f);
		}
	}

	int idx = 0;
	for (int i = 0; i < altoPx -1; ++i){
		GLuint* vecIndices = new GLuint[ this->m_cantIndicesXFranja ];

		for (int j = 0; j < this->m_cantIndicesXFranja; ++j){
			vecIndices[j] = idx;
			vecIndices[++j] = idx + anchoPx;
			++idx;
		}

		this->m_indexBuffer.push_back( vecIndices );
	}
}


Lona::~Lona(){
	delete[] this->m_vertices;
	for (auto it = this->m_indexBuffer.begin(); it != this->m_indexBuffer.end(); ++it){
		delete[] (*it);
	}
}


void Lona::dibujar(const glm::mat4 &viewProjection, const glm::mat4 &model, GLuint shaderProgramID) const {
	glUseProgram(shaderProgramID);

	// Bindea las matrices del modelo
	GLint locViewProj = glGetUniformLocation(shaderProgramID, "viewProjection"); 
	if (locViewProj == -1) throw std::runtime_error("No existe el parametro 'viewProjection' en el shader");

	GLint locModelMatrix = glGetUniformLocation(shaderProgramID, "model"); 
	if (locModelMatrix == -1) throw std::runtime_error("No existe el parametro 'model' en el shader");

	// Bindea el color
	GLint locColor = glGetUniformLocation(shaderProgramID, "color");
	if (locColor == -1) throw std::runtime_error("No existe el parametro 'color' en el shader");

	GLint locTiempo = glGetUniformLocation(shaderProgramID, "tiempo");
	if (locTiempo == -1) throw std::runtime_error("No existe el parametro 'tiempo' en el shader");

	GLint locLong = glGetUniformLocation(shaderProgramID, "longitud");
	if (locLong == -1) throw std::runtime_error("No existe el parametro 'longitud' en el shader");

	// Empieza a dibujar todo
	glEnableClientState(GL_VERTEX_ARRAY);

	// Las matrices del modelo
	glUniformMatrix4fv(locViewProj, 1, GL_FALSE, &viewProjection[0][0]);
	glUniformMatrix4fv(locModelMatrix, 1, GL_FALSE, &model[0][0]);

	// El color
	glUniform3f(locColor, 0.4f, 0.0f, 0.4f);

	// El tiempo y la longitud de la lona
	static GLfloat tiempo = 0.0f;
	tiempo += 0.01f;
	glUniform1f(locTiempo, tiempo);
	glUniform1f(locLong, this->m_longitud);

	// Los vertices de la figura
	glVertexPointer(3, GL_FLOAT, 0, this->m_vertices);

	// Va dibujando el elemento por franjas usando vertices
	for (auto it = this->m_indexBuffer.cbegin(); it != this->m_indexBuffer.cend(); ++it){
		glDrawElements(GL_TRIANGLE_STRIP, this->m_cantIndicesXFranja, GL_UNSIGNED_INT, *it);
	}

	glDisableClientState(GL_VERTEX_ARRAY);
}


